﻿using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class TimeTest
{
    [TestMethod]
    public void TimeConstructorTest()
    {
        uint hours = 21;
        uint minutes = 55;
        Time target = new Time(hours, minutes);
        Assert.AreEqual(target.Hours, hours);
        Assert.AreEqual(target.Minutes, minutes);
    }

    [TestMethod]
    public void TimeConstructorOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 66;
        Time target = new Time(hours, minutes);
        Assert.AreEqual(target.Hours, hours + 1);
        Assert.AreEqual(target.Minutes, minutes % 60);
    }

    [TestMethod]
    public void TimeConstructorOverflowHours()
    {
        uint hours = 24;
        uint minutes = 13;
        Time target = new Time(hours, minutes);
        Assert.AreEqual(target.Hours, (uint)0);
        Assert.AreEqual(target.Minutes, minutes);
    }

    [TestMethod]
    public void TimeConstructorOverflowHoursAndMinutes()
    {
        uint hours = 24;
        uint minutes = 65;
        Time target = new Time(hours, minutes);
        Assert.AreEqual(target.Hours, (uint)1);
        Assert.AreEqual(target.Minutes, (uint)5);
    }

    [TestMethod]
    public void TimePlusBasic()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start + 5;
        Assert.AreEqual(target.Hours, start.Hours);
        Assert.AreEqual(target.Minutes, start.Minutes + 5);
    }

    [TestMethod]
    public void TimePlusOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start + 40;
        Assert.AreEqual(target.Hours, start.Hours + 1);
        Assert.AreEqual(target.Minutes, (uint)2);
    }

    [TestMethod]
    public void TimePlusOverflowMinutesAndHours()
    {
        uint hours = 23;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start + 40;
        Assert.AreEqual(target.Hours, (ulong)0);
        Assert.AreEqual(target.Minutes, (ulong)2);
    }

    [TestMethod]
    public void TimePlusNegative()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start + (-20);
        Assert.AreEqual(target.Hours, start.Hours);
        Assert.AreEqual(target.Minutes, start.Minutes - 20);
    }

    [TestMethod]
    public void TimePlusNegativeOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start + (-40);
        Assert.AreEqual(target.Hours, start.Hours - 1);
        Assert.AreEqual(target.Minutes, start.Minutes + 20);
    }

    [TestMethod]
    public void TimePlusNegativeOverflowHoursAndMinutes()
    {
        uint hours = 0;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start + (-40);
        Assert.AreEqual(target.Hours, (ulong)23);
        Assert.AreEqual(target.Minutes, (ulong)42);
    }

    [TestMethod]
    public void TimeMinusBasic()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start - 4;
        Assert.AreEqual(target.Hours, hours);
        Assert.AreEqual(target.Minutes, minutes - 4);
    }

    [TestMethod]
    public void TimeMinusOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start - 40;
        Assert.AreEqual(target.Hours, start.Hours - 1);
        Assert.AreEqual(target.Minutes, (uint)42);
    }

    [TestMethod]
    public void TimeMinusOverflowMinutesAndHours()
    {
        uint hours = 0;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start - 40;
        Assert.AreEqual(target.Hours, (ulong)23);
        Assert.AreEqual(target.Minutes, (ulong)42);
    }

    [TestMethod]
    public void TimeMinusNegative()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start - (-20);
        Assert.AreEqual(target.Hours, start.Hours);
        Assert.AreEqual(target.Minutes, start.Minutes + 20);
    }

    [TestMethod]
    public void TimeMinusNegativeOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start - (-40);
        Assert.AreEqual(target.Hours, start.Hours + 1);
        Assert.AreEqual(target.Minutes, start.Minutes - 20);
    }

    [TestMethod]
    public void TimeMinusNegativeOverflowHoursAndMinutes()
    {
        uint hours = 23;
        uint minutes = 22;
        Time start = new Time(hours, minutes);
        Time target = start - (-40);
        Assert.AreEqual(target.Hours, (ulong)0);
        Assert.AreEqual(target.Minutes, (ulong)2);
    }

    [TestMethod]
    public void TimeIncrementBasic()
    {
        uint hours = 12;
        uint minutes = 22;
        Time target = new Time(hours, minutes);
        Time expected = target + 1;
        target++;
        Assert.AreEqual(expected.Hours, target.Hours);
        Assert.AreEqual(expected.Minutes, target.Minutes);
    }

    [TestMethod]
    public void TimeIncrementOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 59;
        Time target = new Time(hours, minutes);
        Time expected = target + 1;
        target++;
        Assert.AreEqual(expected.Hours, target.Hours);
        Assert.AreEqual(expected.Minutes, target.Minutes);
    }

    [TestMethod]
    public void TimeIncrementOverflowMinutesAndHours()
    {
        uint hours = 23;
        uint minutes = 59;
        Time target = new Time(hours, minutes);
        Time expected = target + 1;
        target++;
        Assert.AreEqual(expected.Hours, target.Hours);
        Assert.AreEqual(expected.Minutes, target.Minutes);
    }

    [TestMethod]
    public void TimeDecrementBasic()
    {
        uint hours = 12;
        uint minutes = 22;
        Time target = new Time(hours, minutes);
        Time expected = target - 1;
        target--;
        Assert.AreEqual(expected.Hours, target.Hours);
        Assert.AreEqual(expected.Minutes, target.Minutes);
    }

    [TestMethod]
    public void TimeDecrementOverflowMinutes()
    {
        uint hours = 12;
        uint minutes = 0;
        Time target = new Time(hours, minutes);
        Time expected = target - 1;
        target--;
        Assert.AreEqual(expected.Hours, target.Hours);
        Assert.AreEqual(expected.Minutes, target.Minutes);
    }

    [TestMethod]
    public void TimeDecrementOverflowMinutesAndHours()
    {
        Time target = new Time();
        Time expected = target - 1;
        target--;
        Assert.AreEqual(expected.Hours, target.Hours);
        Assert.AreEqual(expected.Minutes, target.Minutes);
    }

    [TestMethod]
    public void ToStringTest()
    {
        Time target = new Time(7, 8);
        string expected = "07:08";
        string actual = target.ToString();
        Assert.AreEqual(expected, actual);
    }
}
